--[[
    新扭蛋抽奖 - 2022-05-06
    zhongyongbo
]]
-- 文件
local gg         = require("modules.business_welfare.welfare_gg")
local config     = require("modules.business_welfare.welfare_lua_config")
local uu         = require("modules.commhm.utils")
local ns_account = require("modules.business_welfare.welfare_bridge")
local log        = require("modules.commhm.log")
local code_conf  = require("modules.business_welfare.welfare_code")
local g_enum     = require("modules.business_welfare.welfare_enum")
local business_welfare_common = require("modules.business_welfare.welfare_common")
local op_log     = require("modules.business_welfare.welfare_op_log")
local utils      = require("modules.business_common.business_utils")
local account    = require("modules.business_common.business_account")
local welfare_gift = require('modules.business_welfare.welfare_gift')

-- 变量 开头定义优先级 系统库 > ngx > 自定义
local pairs      = pairs
local math       = math
local random = gg.random
local table_insert = table.insert
local ngx = ngx

local error_code = code_conf.error_code

local FOO = {}


FOO.get_lottery_cfg = function(id)
    local cfg = config.get_cfg('welfare_lottery_mall')
    return cfg and cfg[id]
end


FOO.get_lottery_rwds_cfg = function(index)
    local cfg = config.get_cfg('welfare_lottery_rewards')
    return cfg and cfg[index]
end

FOO.get_lottery_ex_cfg = function(index)
    local cfg = config.get_cfg('welfare_lottery_exchange')
    return cfg and cfg[index]
end


local get_userdata = function()
    return gg.get_ssdb_cache_info(gg.KEYS.WELFARE_LOTTERYY) or {}
end


local set_userdata = function( userdata )
    gg.set_ssdb_cache_info(gg.KEYS.WELFARE_LOTTERYY, userdata)
end


--! @ 扭蛋抽奖
FOO.welfare_lottery_buy = function()
    local buy_id = tonumber(ngx.ctx.m_params.buy_id) or 0
    local buy_times = tonumber(ngx.ctx.m_params.buy_times) or 0

    --配置检查
    local cfg = FOO.get_lottery_cfg(buy_id)
    if not cfg then
        return error_code.ERROR_CONFIG
    end


    -- 2 获取玩家数据
    local userdata = get_userdata()
    if not userdata then
        return error_code.ERROR_NO_DATA
    end

    FOO.flush_lottery_data(userdata)

    -- 检查限购次数
    if not FOO.buy_limit_check(cfg, userdata, buy_times* cfg.times) then
        return error_code.ERROR_LIMIT_TIMES
    end

    local cost_id = welfare_gift.PRICE_TYPE[cfg.pricetype]
    local cost_num = cfg.price*buy_times
    local ret, items = FOO.use_item_get_gift(userdata, cfg, cost_id, cost_num, buy_times * cfg.times, 'welfare_lottery', buy_id)
    if ret ~= error_code.COMMON_SUCCESS then
        return ret
    end

    set_userdata(userdata)

    return ret, items
end


--! @ 购买检查
FOO.buy_limit_check = function(cfg, userdata, buy_times)
    if cfg.show_type ~= g_enum.lottery.show_type.half and cfg.show_type ~= g_enum.lottery.show_type.free then
        return true
    end
    if buy_times ~= 1 then
        return false
    end
    local lottery = userdata.lottery or {}
    if cfg.show_type == g_enum.lottery.show_type.free and lottery.had_free then  --免费次数已用
        return false
    elseif cfg.show_type == g_enum.lottery.show_type.half and lottery.had_half then --半价次数已用
        return false
    end
    return true
end


--! @ 设置数据 
FOO.buy_set_data = function(cfg, userdata, times, giftid)
    userdata.lottery = userdata.lottery or {}
    if cfg.show_type == g_enum.lottery.show_type.free then  --免费次数已用
        userdata.lottery.had_free = true
    elseif cfg.show_type == g_enum.lottery.show_type.half then --半价次数已用
        userdata.lottery.had_half = true
    end
    if cfg.type == g_enum.lottery.type.dream_lottery then
        userdata.lottery.dream_lottery_times = (userdata.lottery.dream_lottery_times or 0) + times
    elseif cfg.type == g_enum.lottery.type.star_lottery then
        userdata.lottery.star_lottery_times = (userdata.lottery.star_lottery_times or 0) + times
    end

    --同步幸运值指向
    if cfg.luckly_dest and cfg.luckly_dest ~= giftid then
        userdata.lucky_value[cfg.luckly_dest] = userdata.lucky_value[giftid]
    end
end


--! @ 使用物品开启礼包 gift_id:礼包id  item_id:物品id item_num:开启一个礼包消耗的物品数量 times:次数
FOO.use_item_get_gift = function(userdata, cfg, item_id, item_num, times, action, buy_id)
    local gift_id = cfg.giftid
    --检查参数
    if times < 1 or times > welfare_gift.MAX_GET_GIFT_LIME then  --单次购买次数限制在 1-20
        return error_code.ERROR_PARAM
    end

    local last_lucky = userdata.lucky_value and userdata.lucky_value[gift_id] or 0

    local ret, drop_items, lucky_value, detail_items = welfare_gift.get_gift(userdata, gift_id, times)
    if ret ~= error_code.COMMON_SUCCESS then
        log.loggerdebug("welfare lottery drops err uin:%% gift_id:%%, times:%%", ngx.ctx.m_params.uin, gift_id, times)
        return ret
    end

    --扣除消耗物品
    if item_num > 0 then
        local ret = ns_account.private_account.item_remove(item_id, item_num, action, {buy_id=buy_id, items=drop_items})
        if not ret then
            log.loggerdebug("welfare lottery item error, ret = %%", ret)
            return error_code.ERROR_DEL_ITEM
        end
    end

    local items = {}
    for _, v in pairs(detail_items or {}) do
        for id, num in pairs(v) do
            items[#items+1] = {id=id, num=num}
        end
    end

    local ret = ns_account.private_account.items_add(items, action)
	if not ret then
        log.day_list("welfare_lottery_add_item", action, ngx.ctx.m_params.uin, uu.to_str(drop_items), uu.now(), uu.to_str(ret))
		return error_code.ERROR_ADD_ITEM
	end

    local loginfo = {
        lucky_value = lucky_value,
        detail_items = detail_items,
        gift_id = gift_id,
        cost_id = item_id,
        cost_num = item_num,
        times = times,
        action = action,
        buy_id = buy_id,
        last_lucky = last_lucky,
    }

    FOO.write_op_log(loginfo)
    --记录购买次数
    FOO.buy_set_data(cfg, userdata, times, gift_id)
    local ret_data = FOO.get_data(userdata)
    ret_data.items = detail_items
    ret_data.gift_id = gift_id

    return error_code.COMMON_SUCCESS, ret_data
end


FOO.write_op_log = function(loginfo)
    op_log.record("welfare_gift", loginfo.action, loginfo)
end


--! @ 刷新数据
FOO.flush_lottery_data = function(userdata)
    local now = uu.now()
    userdata.lottery = userdata.lottery or {}
    local is_flush = false

    if not (userdata.lottery.last_flush_time_day and business_welfare_common.is_same_day(now, userdata.lottery.last_flush_time_day) ) then
        userdata.lottery.last_flush_time_day = now
        userdata.lottery.had_free = false --免费刷新
        userdata.lottery.had_half = false --半价刷新
        is_flush = true
    end

    if not (userdata.lottery.last_flush_time_week and business_welfare_common.is_same_week(now, userdata.lottery.last_flush_time_week) ) then
        userdata.lottery.last_flush_time_week = now
        userdata.lottery.dream_lottery_times = 0
        userdata.lottery.star_lottery_times = 0
        userdata.lottery.index_map = {}
        is_flush = true
    end

    return is_flush
end


FOO.get_data = function (userdata)
    local hap_pick_rewards = {}
    for k, v in pairs(userdata.lottery.index_map or {}) do
        hap_pick_rewards[#hap_pick_rewards+1] = k
    end

    return {
        had_free = userdata.lottery.had_free and 0 or 1,
        had_half = userdata.lottery.had_half and 0 or 1,
        dream_lottery_times = userdata.lottery.dream_lottery_times or 0,
        star_lottery_times = userdata.lottery.star_lottery_times or 0,
        hap_pick_rewards = hap_pick_rewards,
        lucky_value = userdata.lucky_value or {},
    }
end


--! @ 查询信息
FOO.welfare_lottery_info = function()
    local userdata = get_userdata()
    if  FOO.flush_lottery_data(userdata) then
        set_userdata(userdata)
    end
    return error_code.COMMON_SUCCESS, FOO.get_data(userdata)
end


--! @ 领取奖励
FOO.welfare_lottery_pick_rewards = function ()
    local index = tonumber(ngx.ctx.m_params.index) or 0
    local type = tonumber(ngx.ctx.m_params.type) or 0
    local cfg = FOO.get_lottery_rwds_cfg(index)
    if not cfg or cfg.type ~= type then
        return error_code.ERROR_PARAM
    end
    local userdata = get_userdata()
    FOO.flush_lottery_data(userdata)

    userdata.lottery = userdata.lottery or {}
    userdata.lottery.index_map = userdata.lottery.index_map or {}
    if userdata.lottery.index_map[index] then
        return error_code.ALREADY_GET_REWARDS
    end
    local times = 0
    if type == g_enum.lottery.type.dream_lottery then
        times = userdata.lottery.dream_lottery_times or 0
    elseif type == g_enum.lottery.type.star_lottery then
        times = userdata.lottery.star_lottery_times or 0
    else
        return error_code.ERROR_PARAM
    end

    if times < cfg.times then
        return error_code.ERROR_NOT_TIMES
    end
    local ret = ns_account.private_account.items_add(cfg.items, "welfare_lottery")
	if not ret then
        log.day_list("welfare_lottery_add_item", "welfare_lottery_exchange", ngx.ctx.m_params.uin, uu.to_str(cfg.items), uu.now(), uu.to_str(ret))
		return error_code.ERROR_ADD_ITEM
	end
    userdata.lottery.index_map[index] = true

    set_userdata(userdata)

    local log_info = {
        action = "welf_lottery_pick_rewards",
        pick_items = cfg.items,
        times = cfg.times,
        index  = index,
        type = type,
    }
    FOO.write_op_log(log_info)

    return error_code.COMMON_SUCCESS, FOO.get_data(userdata)
end


--! @ 兑换奖励
FOO.welfare_lottery_exchange = function()
    local index = tonumber(ngx.ctx.m_params.index) or 0
    local cfg = FOO.get_lottery_ex_cfg(index)
    if not cfg then
        return error_code.ERROR_PARAM
    end

    local action =  "welfare_lottery"
    local ret = ns_account.private_account.item_remove(cfg.costid, cfg.costnum, action)
    if not ret then
        log.loggerdebug("welfare lottery item error, ret = %%", ret)
        return error_code.ERROR_DEL_ITEM
    end

    local ret = ns_account.private_account.items_add(cfg.items, action)
	if not ret then
        log.day_list("welfare_lottery_add_item", action, ngx.ctx.m_params.uin, uu.to_str(cfg.items), uu.now())
		return error_code.ERROR_ADD_ITEM
	end

    local log_info = {
        action = "welfare_lottery_exchange",
        cost_id = cfg.costid,
        cost_num = cfg.costnum,
        items = cfg.items,
    }
    FOO.write_op_log(log_info)

    return error_code.COMMON_SUCCESS
end


return FOO